#ifndef MEMORYIMAGE_H
#define MEMORYIMAGE_H

#include "crossbit/common.h"

namespace crossbit {

    class MemoryImage {
        public:
            MemoryImage(XTPStr image, 
                    XTUint32 argc, 
                    XTPStr argv[], 
                    XTPStr envp[]) 
                : 	mi_image(image),
                mi_argc(argc),
                mi_argv(argv),
                mi_envp(envp)
        {}

            virtual ~MemoryImage() {}

            // Create address space for source executable Return true if
            // successful, otherwise return false
            virtual bool load() = 0;

            // Return program entry point
            XTMemAddr entry() const
            {
                return mi_entry;
            }

            XTMemAddr brk() const
            {
                return mi_brk;
            }

            XTMemAddr stack() const
            {
                return mi_stack;
            }

			// added by zhangyichao
			// Return the start addr of section .text
			XTMemAddr text_start() const
			{
				return mi_text_start;
			}

			// added by zhangyichao
			// Return the end addr of section .text
			XTMemAddr text_end() const
			{
				return mi_text_end;
			}

#if 0
            // Change the data segment size
            // 
            // Rationale: Generally speaking, it's brk syscall brk's job to
            // manage the data segment.  But in the conteXT of a guest address
            // space, only class MemoryImage knows how to locate, enlarge or
            // shrink the data segment. So the implementation of brk syscall
            // just invoke MemoryImage::brk.
            virtual bool brk(XTMemAddr brk)  = 0;
#endif

            // Perform source-to-target address mapping.  The translation
            // mechanism depends on the implementation.
            virtual XTMemAddr map(XTMemAddr srcAddr) {
                return srcAddr;
            } 

            XTMemAddr brk( int a , int b)
            {
                if( a != 0 ){
                    mi_brk = a; 
                    return a;
                }
                else return mi_brk;
               
              //  return mi_brk;

                
            }

        protected:

            // Return stack top after initial
            virtual XTMemAddr setupStack( XTMemAddr base ) = 0;

            // *Initial* address of program entry point, stack top, and break
            // point. They are not updated during runtime.
            //
            // These values are supposed to be passed to Interpreter for proper
            // initialization of source processor state.

            XTPStr		mi_image;	
            XTUint32	mi_argc;
            XTPStr		*mi_argv;
            XTPStr		*mi_envp;

            XTInt32		mi_file; //file description
            XTMemAddr	mi_entry;
            XTMemAddr	mi_brk;
            XTMemAddr	mi_stack;

			// added by zhangyichao
			// for static analysis
			XTMemAddr	mi_text_start;
			XTMemAddr	mi_text_end;
    };
}

#endif
